package com.aiyige.utils.banner;

import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.aiyige.utils.ListUtil;
import com.aiyige.utils.banner.model.BannerIndicatorItem;

import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by zhuyakun on 2017/10/16.
 */

public class BannerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener {
    public static final String TAG = BannerAdapter.class.getSimpleName();
    List<BannerFrag> bannerFragList = new LinkedList<>();
    Banner banner;
    boolean bannerScrollable = true;
    Timer autoScrollTimer;
    Handler mainHandler;
    RecyclerView indicator;
    BannerIndicatorAdapter bannerIndicatorAdapter;
    long bannerIdleTimestamp = 0;

    public BannerAdapter(FragmentManager fm) {
        super(fm);
        mainHandler = new Handler(Looper.getMainLooper());
        bannerIndicatorAdapter = new BannerIndicatorAdapter();
    }

    @Override
    public int getItemPosition(Object object) {
        return PagerAdapter.POSITION_NONE;
    }

    public void setData(List<Data> dataList) {
        if (ListUtil.isEmpty(dataList)) {
            dataList = new LinkedList<>();
            BannerAdapter.Data bannerAdapterData = new BannerAdapter.Data();
            bannerAdapterData.setId("");
            bannerAdapterData.setUrl("");
            bannerAdapterData.setRouter("");
            dataList.add(bannerAdapterData);
        }
        List<Data> tempDataList = new LinkedList<>();
        switch (dataList.size()) {
            case 1:
                bannerScrollable = false;
                for (int i = 0; i < 3; ++i) {
                    tempDataList.add(new Data(dataList.get(0)));
                }
                break;
//            case 2:
//                bannerScrollable = true;
//                for (int i = 0; i < 2; ++i) {
//                    tempDataList.add(new Data(dataList.get(0)));
//                    tempDataList.add(new Data(dataList.get(1)));
//                }
//                break;
            default:
                bannerScrollable = true;
                tempDataList.addAll(dataList);
                break;
        }
        processData(tempDataList);
    }

    public void processData(List<Data> dataList) {
        bannerIndicatorAdapter.setNewData(new LinkedList<BannerIndicatorItem>());
        bannerIndicatorAdapter.addData(BannerIndicatorItem.newBuilder()
                .type(BannerIndicatorItem.TYPE_PLACEHOLDER)
                .build());
        bannerIndicatorAdapter.addData(BannerIndicatorItem.newBuilder()
                .type(BannerIndicatorItem.TYPE_PLACEHOLDER)
                .build());
        for (Data item : dataList) {
            bannerIndicatorAdapter.addData(BannerIndicatorItem.newBuilder()
                    .type(bannerScrollable ? BannerIndicatorItem.TYPE_NORMAL : BannerIndicatorItem.TYPE_PLACEHOLDER)
                    .selected(false)
                    .build());
        }
        bannerIndicatorAdapter.addData(BannerIndicatorItem.newBuilder()
                .type(BannerIndicatorItem.TYPE_PLACEHOLDER)
                .build());
        bannerIndicatorAdapter.addData(BannerIndicatorItem.newBuilder()
                .type(BannerIndicatorItem.TYPE_PLACEHOLDER)
                .build());

        bannerFragList.clear();
        bannerFragList.add(BannerFrag.newInstance(new Data(dataList.get(dataList.size() - 2))));
        bannerFragList.add(BannerFrag.newInstance(new Data(dataList.get(dataList.size() - 1))));
        for (Data item : dataList) {
            bannerFragList.add(BannerFrag.newInstance(new Data(item)));
        }
        bannerFragList.add(BannerFrag.newInstance(new Data(dataList.get(0))));
        bannerFragList.add(BannerFrag.newInstance(new Data(dataList.get(1))));
        notifyDataSetChanged();
        configBanner();
        if (autoScrollTimer != null) {
            autoScrollTimer.cancel();
        }
        if (bannerScrollable) {
            autoScrollTimer = new Timer();
            autoScrollTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    if (banner != null) {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (System.currentTimeMillis() - bannerIdleTimestamp > 1000) {
                                    banner.setCurrentItem(banner.getCurrentItem() + 1);
                                }
                            }
                        });
                    }
                }
            }, 0, 3000);
        }
    }

    public void destory() {
        if (autoScrollTimer != null) {
            autoScrollTimer.cancel();
        }
    }


    public void setupWithBanner(Banner b) {
        if (banner != null) return;
        banner = b;
        banner.setAdapter(null);
        banner.setAdapter(this);
        banner.setPageTransformer(false, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                float v = Math.abs(position);
                float v1 = 0.2f * (v * v);
                page.setScaleY(1 - v1);
                View bannerParent = (View) banner.getParent();
                if (bannerParent != null) {
                    bannerParent.postInvalidate();
                }
            }
        });
        banner.setOffscreenPageLimit(Integer.MAX_VALUE);
        banner.addOnPageChangeListener(this);
    }

    public void setupWithIndicator(RecyclerView indicator) {
        if (this.indicator != null) return;
        this.indicator = indicator;
        indicator.setLayoutManager(new LinearLayoutManager(indicator.getContext(), LinearLayoutManager.HORIZONTAL, false));
        bannerIndicatorAdapter.bindToRecyclerView(indicator);
    }

    public void configBanner() {
        if (banner == null) return;
        banner.setScrollable(isBannerScrollable());
        banner.setCurrentItem(2, false);
        notifyDataSetChanged();
        View bannerParent = (View) banner.getParent();
        if (bannerParent != null) {
            bannerParent.postInvalidate();
        }
        BannerIndicatorItem bannerIndicatorItem = bannerIndicatorAdapter.getItem(2);
        if (bannerIndicatorItem != null) {
            bannerIndicatorItem.setSelected(true);
            bannerIndicatorAdapter.setData(2, bannerIndicatorItem);
        }
//        mainHandler.post(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    if (banner.beginFakeDrag()) {
//                        banner.fakeDragBy(0);
//                        banner.endFakeDrag();
//                    }
//                }catch (Exception e){}
//            }
//        });
    }


    @Override
    public Fragment getItem(int position) {
        return bannerFragList.get(position);
    }

    public boolean isBannerScrollable() {
        return bannerScrollable;
    }


    @Override
    public int getCount() {
        return bannerFragList.size();
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (positionOffsetPixels == 0) {
            if (position >= getCount() - 2) {
                banner.setCurrentItem(2, false);
            } else if (position <= 1) {
                banner.setCurrentItem(getCount() - 3, false);
            }
        }

        if (position >= getCount() - 2) {
            for (BannerIndicatorItem bannerIndicatorItem : bannerIndicatorAdapter.getData()) {
                bannerIndicatorItem.setSelected(false);
            }
            BannerIndicatorItem bannerIndicatorItem = bannerIndicatorAdapter.getItem(2);
            bannerIndicatorItem.setSelected(true);
            bannerIndicatorAdapter.notifyDataSetChanged();
        } else if (position <= 1) {
            for (BannerIndicatorItem bannerIndicatorItem : bannerIndicatorAdapter.getData()) {
                bannerIndicatorItem.setSelected(false);
            }
            BannerIndicatorItem bannerIndicatorItem = bannerIndicatorAdapter.getItem(getCount() - 3);
            bannerIndicatorItem.setSelected(true);
            bannerIndicatorAdapter.notifyDataSetChanged();
        } else {
            for (BannerIndicatorItem bannerIndicatorItem : bannerIndicatorAdapter.getData()) {
                bannerIndicatorItem.setSelected(false);
            }
            BannerIndicatorItem bannerIndicatorItem = bannerIndicatorAdapter.getItem(position);
            bannerIndicatorItem.setSelected(true);
            bannerIndicatorAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        switch (state) {
            case ViewPager.SCROLL_STATE_IDLE:
                bannerIdleTimestamp = System.currentTimeMillis();
                break;
            default:
                bannerIdleTimestamp = Long.MAX_VALUE;
                break;
        }
    }

    public static class Data {
        private String id;
        private String title;
        private int activityId;
        private String url;
        private String link;
        private String router;
        private int type;
        private String owner;
        private int orderMe;
        private int status;
        private long createTime;
        private String updateTime;

        public Data() {

        }


        public Data(Data other) {
            url = other.getUrl();
            router = other.getRouter();
            link = other.getLink();
            id = other.getId();
            title = other.getTitle();
            activityId = other.getActivityId();
            type = other.getType();
            owner = other.getOwner();
            orderMe = other.getOrderMe();
            status = other.getStatus();
            createTime = other.getCreateTime();
            updateTime = other.getUpdateTime();
        }

        private Data(Builder builder) {
            setId(builder.id);
            setTitle(builder.title);
            setActivityId(builder.activityId);
            setUrl(builder.url);
            setLink(builder.link);
            setRouter(builder.router);
            setType(builder.type);
            setOwner(builder.owner);
            setOrderMe(builder.orderMe);
            setStatus(builder.status);
            setCreateTime(builder.createTime);
            setUpdateTime(builder.updateTime);
        }

        public static Builder newBuilder() {
            return new Builder();
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public int getActivityId() {
            return activityId;
        }

        public void setActivityId(int activityId) {
            this.activityId = activityId;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getLink() {
            return link;
        }

        public void setLink(String link) {
            this.link = link;
        }

        public String getRouter() {
            return router;
        }

        public void setRouter(String router) {
            this.router = router;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public String getOwner() {
            return owner;
        }

        public void setOwner(String owner) {
            this.owner = owner;
        }

        public int getOrderMe() {
            return orderMe;
        }

        public void setOrderMe(int orderMe) {
            this.orderMe = orderMe;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public long getCreateTime() {
            return createTime;
        }

        public void setCreateTime(long createTime) {
            this.createTime = createTime;
        }

        public String getUpdateTime() {
            return updateTime;
        }

        public void setUpdateTime(String updateTime) {
            this.updateTime = updateTime;
        }

        public static final Data DUMMY_ITEM = new Data();

        public static final class Builder {
            private String id;
            private String title;
            private int activityId;
            private String url;
            private String link;
            private String router;
            private int type;
            private String owner;
            private int orderMe;
            private int status;
            private long createTime;
            private String updateTime;

            private Builder() {
            }

            public Builder id(String id) {
                this.id = id;
                return this;
            }

            public Builder title(String title) {
                this.title = title;
                return this;
            }

            public Builder activityId(int activityId) {
                this.activityId = activityId;
                return this;
            }

            public Builder url(String url) {
                this.url = url;
                return this;
            }

            public Builder link(String link) {
                this.link = link;
                return this;
            }

            public Builder router(String router) {
                this.router = router;
                return this;
            }

            public Builder type(int type) {
                this.type = type;
                return this;
            }

            public Builder owner(String owner) {
                this.owner = owner;
                return this;
            }

            public Builder orderMe(int orderMe) {
                this.orderMe = orderMe;
                return this;
            }

            public Builder status(int status) {
                this.status = status;
                return this;
            }

            public Builder createTime(long createTime) {
                this.createTime = createTime;
                return this;
            }

            public Builder updateTime(String updateTime) {
                this.updateTime = updateTime;
                return this;
            }

            public Data build() {
                return new Data(this);
            }
        }
    }

}
